<?php

declare(strict_types=1);

namespace app\admin\logic\server;

use app\common\model\server\Consumer;
use app\common\model\server\Chats;
use app\common\model\server\Product;
use app\common\model\server\Setting;
use app\common\model\server\Sentence;
use app\common\model\server\Comment;
use app\common\model\system\SysUser;
use app\api\controller\Event;
use app\admin\logic\server\SettingLogic;
use app\admin\logic\server\RobotLogic;
use app\admin\logic\server\SentenceLogic;
use app\admin\logic\system\SysUserLogic;
use GatewayWorker\Lib\Gateway;

/**
 * 客户列表
 */
class ConsumerLogic

{
    /**
     * @notes 客户列表
     * @param array $param
     * @return \think\response\Json
     */
    public static function list(array $param)
    {
        $list = Consumer::custom($param)
            ->field('id,uid,name,avatar,group_id,state,ip,created_at,is_online')
            ->with('group')
            ->order('id desc')
            ->pages($param)
            ->select();
        return list_fmt($list, Consumer::custom($param)->count());
    }
    /**
     * 认领客户并执行后续处理
     *
     * @param array $params 客服认领参数，含客服ID
     * @return mixed 更新结果
     */
    public function claim(array $params)
    {
        // 查询未分配客服的首个客户
        $consumer = Consumer::whereNull('kefu_id')
                        ->order('id', 'asc')
                        ->findOrEmpty();
        if ($consumer->isEmpty()) {
            return; // 无未认领客户直接结束
        }
        // 分配客服并更新记录
        $consumer->kefu_id = $params['kefu_id'];
        $consumer->save();
        // 准备发送客服信息、系统设置和回复语句
        $sysUserInfo = SysUserLogic::details(['id' => $params['kefu_id']])->toArray();
        $settings = SettingLogic::detail();
        $replySentences = SentenceLogic::getAll(['kefu_id' => $params['kefu_id']]);
        // 随机选取回复语句并发送给客户
        if (!empty($replySentences)) {
            $randomIndex = $sysUserInfo['is_reply'] == 2 ? rand(0, count($replySentences) - 1) : 0;
            $welcomeMessage = strip_tags($replySentences[$randomIndex]['content']);
            $this->sendWelcomeChat($consumer->uid, $params['kefu_id'], $welcomeMessage, $sysUserInfo);
        }
        return true; // 成功认领客户
    }
    public function census(array $params){
        $date=!empty($params['date']) ? $params['date'] : date('Y-m-d');
        $data=Product::whereTime('created_at', '>=', strtotime($date))->select();
        $productIdList=array_column($data->toArray(),'product_id');
        $data['arrayValue']=array_count_values($productIdList);
        $where=[];
        if($params['kid']>2){
            $where['kefu_id']=$params['kid'];
        }
        $data['currentNum']=Consumer::where($where)->where(['is_online'=>1])->count();
        $data['queueNum']=Consumer::where($where)->count();
        $data['onlineServerNum']=SysUser::where(['state'=>1])->count();
        $data['currentAllNum']=Consumer::where($where)->count();
        $data['chatNumToday']=Chats::where($where)->whereTime('created_at', '>=', 'today')->count();
        $data['chatAllNum']=Chats::where($where)->count();
        $data['commentNumToday']=Comment::where($where)->whereTime('created_at', '>=', 'today')->count();
        $data['commentAllNum']=Comment::where($where)->count();
        return $data->toArray();
    }
    /**
     * 创建并发送欢迎消息给客户
     *
     * @param int $uid 客户ID
     * @param int $kefuId 客服ID
     * @param string $message 欢迎消息内容
     * @param array $sysUserInfo 客服信息
     */
    private function sendWelcomeChat($uid, $kefuId, $message, $sysUserInfo)
    {
        Chats::create([
            'kefu_id' => $kefuId,
            'uid' => $uid,
            'content' => $message,
            'direction' => 2,
        ]);

        Event::sendUid($uid, [
            'type' => 'claim',
            'msg' => '您已被认领',
            'server' => $sysUserInfo,
            'message' => $message,
        ]);
    }
    /**
     * 处理主页逻辑，包括用户绑定、状态检查、数据写入及客服列表发送等
     *
     * @param string $clientId 客户端唯一标识
     * @param array $data 包含用户相关信息的数据
     */
    public static function home($client_id,$data){
        // 绑定客户端与用户ID的关系
        Event::addUid($client_id,$data['uid']);
         // 查询用户详细信息
        $user=self::detail(['uid'=>$data['uid']]);
         // 检查用户是否在黑名单中
        if(!empty($user) && $user['state']==3){
            // 用户被加入黑名单，拒绝访问并发送通知
            return Event::sendUid($data['uid'],['type'=>'no_server','msg'=>'您已被加入黑名单，禁止访问']);
        }
        // 如果用户存在且当前状态为离线，则更新状态为在线并增加登录次数
        if(!empty($user) && $user['is_online']==0){
            self::edit(['id'=>$user['id'],'is_online'=>1,'login_num'=>$user['login_num']+1,'product'=>$data['product']]);//修改访客状态
            if($user['kefu_id']) self::sendOnlineList($user['kefu_id']);// 如果用户已绑定客服，通知客服更新在线列表
        } 
         // 如果用户记录不存在，则创建新记录
        if(!$user){
            $data['ip']=getIp();// 补充IP地址信息
            $user=self::edit($data);
        }
       // 获取问答列表并发送给用户
        $robot=RobotLogic::lists(['type'=>1]);
        Event::sendUid($data['uid'],['type'=>'robotlist','msg'=>'问答列表','data'=>$robot]);
          // 查询并应用客服设置
        $setting=SettingLogic::detail();
        if($setting)
           SysUserLogic::serverList($user,$setting,$client_id);
    }
     /**
     * 向指定客服发送在线/离线用户列表
     *
     * @param int $kefuId 客服ID
     */
    public static function sendOnlineList($kefu_id){
        // 获取指定客服的在线用户列表，按置顶状态降序排序
        $onlinelist=self::getAll(['kefu_id'=>$kefu_id,'is_online'=>1],'is_top desc');
        // 向客服发送在线用户列表
        Event::sendUid($kefu_id,['type'=>'onlinelist','msg'=>'在线列表','onlinelist'=>$onlinelist]); 
    }
     /**
     * 修改客服或用户离线状态
     *
     * @param string $clientId 客户端ID
     */
    public static function editOnline($client_id){
        $data=!empty(session($client_id)) ? session($client_id) : []; // 从会话中获取用户数据
        if(!$data) return false;
        if(!empty($data['uid'])){
            self::edit(['id'=>$data['id'],'uid'=>$data['uid'],'is_online'=>0]);// 如果存在用户ID，则修改访客状态为离线
            if($data['kefu_id']) self::sendOnlineList($data['kefu_id']);// 若有绑定的客服，通知客服更新在线列表
            return;
        }
        SysUserLogic::editUser(['id'=>$data['id'],'state'=>2]);// 若是客服操作，修改客服状态为离线
        Event::offGroup($client_id,'serverlist'); // 客服离线，从客服群组中移除
    }
    /**
     * 用户前端点击绑定客服操作
     *
     * @param array $data 包含uid和kefu_id的数据
     */
    public static function selectServer($data){
        // 更新用户绑定的客服ID
        Consumer::where('uid',$data['uid'])->update(['kefu_id'=>$data['kefu_id']]);
         // 获取用户详情
        if(self::detail($data)) 
            // 根据回复策略获取回复语句
            SentenceLogic::getSentence($data['kefu_id'],$data['uid']);
    }
    
     /**
     * 向客服发送其负责的在线用户列表
     *
     * @param array $data 包含kefu_id的数据
     * @return mixed 发送操作的结果
     */
    public static function addServerList($data){
         // 获取在线用户列表
        $onlinelist=self::getAll(['kefu_id'=>$data['kefu_id'],'is_online'=>1],'is_top desc');
        // 发送给客服
        return Event::sendUid($data['kefu_id'], ['type'=>'onlinelist','msg'=>'在线列表','onlinelist'=>$onlinelist]);
    }
    /**
     * 更新排队列表并向相关群组广播
     */
    public static function addPdList($data){
         // 获取未分配客服的用户列表（排队中的用户）
        $queueList=self::getAll(['kefu_id'=>NULL],'id asc');
        // 提取用户ID数组
        $uidList=array_column($queueList->toArray(),'uid');
        // 广播排队列表给排队列表群组
        Event::sendGroup('pdlist',['type'=>'pdlist','msg'=>'成功','pdlist'=>$uidList]);
        // 广播给客服列表群组
        Event::sendGroup('serverlist',['type'=>'serverlist','msg'=>'成功','pdlist'=>$queueList]);
    }
     /**
     * 加入或移出黑名单操作
     *
     * @param array $data 包含uid和type（操作类型）的数据
     */
    public static function blackList($data){
        // 确定消息内容
        $msg= $data['type']==3 ? '您已被加入黑名单' : '您已被移出黑名单';
         // 更新用户状态
        Consumer::where('uid',$data['uid'])->update(['state'=>$data['type']]);
         // 通知用户
        Event::sendUid($data['uid'], ['type'=>'black','msg'=>$msg]);
    }
    /**
     * 生成并发送唯一用户标识（UID）
     *
     * @param string $clientId 客户端ID
     */
     public static function createUid($client_id){
        $data['type']='home';
        // 生成时间戳和随机字符串组合的UID
        $data['uid']=bin2hex(pack('N', time())).strtolower(rands(8));
         // 发送给客户端
        Event::sendClient($client_id,$data);
    }
    /**
     * @notes 客户列表
     * @param array $param
     * @return \think\response\Json
     */
    public static function getOnline($param){
        $param['state']=1;
       if(isset($param['is_online']) && $param['is_online']){
           switch ($param['is_online']) {
	        case '1'://在线列表
	            break;
            case '3'://离线列表
                $param['is_online']=0;
                break;
           }
        }
        //->append(['no_read'])

        $list = (new Consumer)->with('msglist')->where($param)
            ->order('is_top desc')
            ->select();
        //
        if($param['is_online'] ==1){
            foreach ($list as $k=>$v){
                //
                $list[$k]['is_online'] =Event::isuidonline($v->uid);
                //unset($list[$k]);
            }
        }

        return count($list)>0 ? $list->toArray() : [];
    }
     /**
     * @notes 查询客户
     * @param array $param
     * @return \think\response\Json
     */
    public static function detail($param,$order='id desc')
    {
        $where = !empty($param['id']) ? ['id'=>$param['id']] : ['uid'=>$param['uid']];
        //->append(['no_read'])
        $user=  (new Consumer)->with('msglist')->where($where)->order($order)->find();
        $user = !empty($user) ? $user->toArray() : [];
        if($user) $client_id=Event::getCidByUid($user['uid']);
        if(!empty($client_id)){
            self::getInfo($user,$client_id[0]);
        }
        return $user;
    }
    
    public static function getInfo($user,$client_id){
        session($client_id,$user,600);
    }
     /**
     * @notes 编辑客户
     * @param array $param
     * @return bool
     */
    public static function edit(array $param)
    {
        
        $user=self::detail($param);
        if($user && isset($param['is_top'])){
            $user['is_top']= $param['is_top'];
            $client_id=Event::getCidByUid($user['uid']);
            if($client_id) session($client_id[0],$user,600);
        } 
        if(!empty($param['group_id'])) $param['group_id']= $param['group_id'][0];
        return !empty($param['id']) ? Consumer::update($param) : Consumer::create($param);
    }
    /**
     * @notes 删除客户
     * @param integer $id
     * @return bool
     */
    public function delete(int $id)
    {
        return Consumer::destroy($id);
    }
    public static function getAll($where,$order='id asc'){
        return Consumer::with('msglist')->where($where)->order($order)->select();
    }
}
